1   /*
2    * Copyright (c) 1997, 1999, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  package java.awt.image;
27  
28  
29  /**
30   * This class defines a lookup table object.  The output of a
31   * lookup operation using an object of this class is interpreted
32   * as an unsigned byte quantity.  The lookup table contains byte
33   * data arrays for one or more bands (or components) of an image,
34   * and it contains an offset which will be subtracted from the
35   * input values before indexing the arrays.  This allows an array
36   * smaller than the native data size to be provided for a
37   * constrained input.  If there is only one array in the lookup
38   * table, it will be applied to all bands.
39   *
40   * @see ShortLookupTable
41   * @see LookupOp
42   */
43  public class ByteLookupTable extends LookupTable {
44  
45      /**
46       * Constants
47       */
48  
49      byte data[][];
50  
51      /**
52       * Constructs a ByteLookupTable object from an array of byte
53       * arrays representing a lookup table for each
54       * band.  The offset will be subtracted from input
55       * values before indexing into the arrays.  The number of
56       * bands is the length of the data argument.  The
57       * data array for each band is stored as a reference.
58       * @param offset the value subtracted from the input values
59       *        before indexing into the arrays
60       * @param data an array of byte arrays representing a lookup
61       *        table for each band
62       * @throws IllegalArgumentException if <code>offset</code> is
63       *         is less than 0 or if the length of <code>data</code>
64       *         is less than 1
65       */
66      public ByteLookupTable(int offset, byte data[][]) {
67          super(offset,data.length);
68          numComponents = data.length;
69          numEntries    = data[0].length;
70          this.data = new byte[numComponents][];
71          // Allocate the array and copy the data reference
72          for (int i=0; i < numComponents; i++) {
73              this.data[i] = data[i];
74          }
75      }
76  
77      /**
78       * Constructs a ByteLookupTable object from an array
79       * of bytes representing a lookup table to be applied to all
80       * bands.  The offset will be subtracted from input
81       * values before indexing into the array.
82       * The data array is stored as a reference.
83       * @param offset the value subtracted from the input values
84       *        before indexing into the array
85       * @param data an array of bytes
86       * @throws IllegalArgumentException if <code>offset</code> is
87       *         is less than 0 or if the length of <code>data</code>
88       *         is less than 1
89       */
90      public ByteLookupTable(int offset, byte data[]) {
91          super(offset,data.length);
92          numComponents = 1;
93          numEntries    = data.length;
94          this.data = new byte[1][];
95          this.data[0] = data;
96      }
97  
98      /**
99       * Returns the lookup table data by reference.  If this ByteLookupTable
100      * was constructed using a single byte array, the length of the returned
101      * array is one.
102      * @return the data array of this <code>ByteLookupTable</code>.
103      */
104     public final byte[][] getTable(){
105         return data;
106     }
107 
108     /**
109      * Returns an array of samples of a pixel, translated with the lookup
110      * table. The source and destination array can be the same array.
111      * Array <code>dst</code> is returned.
112      *
113      * @param src the source array.
114      * @param dst the destination array. This array must be at least as
115      *         long as <code>src</code>.  If <code>dst</code> is
116      *         <code>null</code>, a new array will be allocated having the
117      *         same length as <code>src</code>.
118      * @return the array <code>dst</code>, an <code>int</code> array of
119      *         samples.
120      * @exception ArrayIndexOutOfBoundsException if <code>src</code> is
121      *            longer than <code>dst</code> or if for any element
122      *            <code>i</code> of <code>src</code>,
123      *            <code>src[i]-offset</code> is either less than zero or
124      *            greater than or equal to the length of the lookup table
125      *            for any band.
126      */
127     public int[] lookupPixel(int[] src, int[] dst){
128         if (dst == null) {
129             // Need to alloc a new destination array
130             dst = new int[src.length];
131         }
132 
133         if (numComponents == 1) {
134             // Apply one LUT to all bands
135             for (int i=0; i < src.length; i++) {
136                 int s = src[i] - offset;
137                 if (s < 0) {
138                     throw new ArrayIndexOutOfBoundsException("src["+i+
139                                                              "]-offset is "+
140                                                              "less than zero");
141                 }
142                 dst[i] = (int) data[0][s];
143             }
144         }
145         else {
146             for (int i=0; i < src.length; i++) {
147                 int s = src[i] - offset;
148                 if (s < 0) {
149                     throw new ArrayIndexOutOfBoundsException("src["+i+
150                                                              "]-offset is "+
151                                                              "less than zero");
152                 }
153                 dst[i] = (int) data[i][s];
154             }
155         }
156         return dst;
157     }
158 
159     /**
160      * Returns an array of samples of a pixel, translated with the lookup
161      * table. The source and destination array can be the same array.
162      * Array <code>dst</code> is returned.
163      *
164      * @param src the source array.
165      * @param dst the destination array. This array must be at least as
166      *         long as <code>src</code>.  If <code>dst</code> is
167      *         <code>null</code>, a new array will be allocated having the
168      *         same length as <code>src</code>.
169      * @return the array <code>dst</code>, an <code>int</code> array of
170      *         samples.
171      * @exception ArrayIndexOutOfBoundsException if <code>src</code> is
172      *            longer than <code>dst</code> or if for any element
173      *            <code>i</code> of <code>src</code>,
174      *            <code>(src[i]&0xff)-offset</code> is either less than
175      *            zero or greater than or equal to the length of the
176      *            lookup table for any band.
177      */
178     public byte[] lookupPixel(byte[] src, byte[] dst){
179         if (dst == null) {
180             // Need to alloc a new destination array
181             dst = new byte[src.length];
182         }
183 
184         if (numComponents == 1) {
185             // Apply one LUT to all bands
186             for (int i=0; i < src.length; i++) {
187                 int s = (src[i]&0xff) - offset;
188                 if (s < 0) {
189                     throw new ArrayIndexOutOfBoundsException("src["+i+
190                                                              "]-offset is "+
191                                                              "less than zero");
192                 }
193                 dst[i] = data[0][s];
194             }
195         }
196         else {
197             for (int i=0; i < src.length; i++) {
198                 int s = (src[i]&0xff) - offset;
199                 if (s < 0) {
200                     throw new ArrayIndexOutOfBoundsException("src["+i+
201                                                              "]-offset is "+
202                                                              "less than zero");
203                 }
204                 dst[i] = data[i][s];
205             }
206         }
207         return dst;
208     }
209 
210 }